package com.edocbase.desktop.search;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class AbstractPageList implements IPageList{

	protected int pageSize = 10;
	protected int page = 1;
	protected int totalPage = 1;
	protected int totalSize = 0;
	protected List<DocumentPage> pageList = new ArrayList<DocumentPage>();
	protected String word = null;
	protected Map<String,Object> parameters = new HashMap<String, Object>();
	public AbstractPageList() {
		super();
	}

	public int getTotalPage() {
		return totalPage;
	}

	public int getTotalSize() {
		return totalSize;
	}

	public String getWord() {
		return word;
	}

	public void setWord(String word) {
		this.word = word;
	}

	public boolean hasNextPage() {
		return page <= totalPage;
	}

	public boolean hasPreviousPage() {
		return page > 0;
	}

	protected void fetchFirstPage() throws Exception {
		page = 1;
		if (page > totalPage){
			pageList = new ArrayList<DocumentPage>(0); 
			return;
		}
		DocumentPage dpage = fetchPage(page);
		if (dpage != null) {
			int p = page - 1;
			pageList.set(p, dpage);
		}
	}

	protected DocumentPage fetchPage(int pageIndex) throws Exception {
		DocumentPage docPage = new DocumentPage(pageSize);
		int start = (pageIndex - 1) * pageSize;
		int end = pageIndex * pageSize;
		end = Math.min(end, totalSize);
		docPage = fetchPage(start, end);
		docPage.setPage(pageIndex);
		return docPage;
	}

	protected abstract DocumentPage fetchPage(int start, int end)
			throws Exception;

	public DocumentPage getNextPage() throws Exception {
		if (hasNextPage()) {
			page = page + 1;
			return getPage(page);
		}
		return null;
	}

	public DocumentPage getPreviousPage() throws Exception {
		if (hasPreviousPage()) {
			page = page - 1;
			return getPage(page);
		}
		return null;
	}

	public DocumentPage getCurrentPage() throws Exception {
		return getPage(page);
	}

	public DocumentPage getPage(int pageIndex) throws Exception {
		DocumentPage docPage = null;
		if (pageIndex <1 || pageIndex > totalPage){
			return null;
		}
		int p = pageIndex - 1;

		if (pageList.get(p) != null) {
			docPage = pageList.get(p);
		} else {
			docPage = fetchPage(pageIndex);
			pageList.set(p, docPage);
		}

		return docPage;
	}

	protected void computePage() {
		double d = new Integer(totalSize).doubleValue()
				/ new Integer(pageSize).doubleValue();
		totalPage = new Double(Math.ceil(d)).intValue();
		pageList = new ArrayList<DocumentPage>(totalPage);
		for (int i = 0; i < totalPage; i++) {
			pageList.add(i, null);
		}
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
		computePage();
		try {
			fetchFirstPage();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Override
	public void close() {
		pageList.clear();
		pageList = null;
	}
	
	public void setParameter(String key,Object v){
		parameters.put(key, v);
	}
	
	public Object getParameter(String key){
		return parameters.get(key);
	}
	public Map<String,Object> getParameters(){
		return parameters;
	}
}